package com.henry.album.util;

import java.util.LinkedList;
import java.util.concurrent.ConcurrentHashMap;


/**
 * 
 * 
 *  安装或鸿蒙  图片内存缓存util
 * @author henry
 *
 * @param <T>  要缓存的数据类型
 */
public class ImageMemCacheUtil<T> {

	public static ConcurrentHashMap<String, CacheItem> cache = new ConcurrentHashMap<>();

	public static int MAX_NUM = 1024;// 最大缓存个数

	public static int currentNum = 0;// 最大缓存个数

	public static long totaldataSize = 0;// 总大小,单位KB最好，字节可能long不够存在

	public static long MAX_SIZE = 1024 * 200;// 最大缓存200M

	public static LinkedList<String> listSort = new LinkedList<>(); // key 排序，，模拟出栈，压栈

	private void setKey(String key) {

		if (listSort.contains(key)) {
			listSort.remove(key);
		}

		listSort.addLast(key);// 翻到最后
	}

	@SuppressWarnings("unchecked")
	public synchronized T getData(String key) {

		weightLoss();

		if (cache.containsKey(key)) {
			CacheItem cacheItem = cache.get(key);
			cacheItem.setLasttime(System.currentTimeMillis());

			setKey(key);// 新的排序

			return (T) cacheItem.getData();
		}

		return null;

	}

	/**
	 * 缓存瘦身
	 */
	private void weightLoss() {

		// 1.先检查个数减肥

		if (currentNum > MAX_NUM) {

			int needRemoveNum = MAX_NUM - currentNum;// 需要删除的个数

			for (int i = 0; i < needRemoveNum; i++) {

				CacheItem cacheItem = cache.get(listSort.get(i));

				totaldataSize -= cacheItem.getDataSize();

				cache.remove(listSort.get(i));

				listSort.remove(i);

				cacheItem = null;
			}

			currentNum = cache.size();// 新的大小

		}

		// 2根据大小减肥

		if (totaldataSize != 0) {

			if (totaldataSize > MAX_SIZE) {// 大于上限200M

				for (int i = 0; i <= MAX_NUM - 1; i++) {

					CacheItem cacheItem = cache.get(listSort.get(i));

					totaldataSize -= cacheItem.getDataSize();

					cache.remove(listSort.get(i));

					listSort.remove(i);

					cacheItem = null;

					if (totaldataSize < MAX_SIZE) {// 小于200M，就跳出
						break;
					}

				}

				currentNum = cache.size();// 新的大小

			}

		}

	}

	public synchronized void setData(String key, T data) {

		setKey(key);// 排序

		currentNum++;

		CacheItem cacheItem = new CacheItem();
		cacheItem.setKey(key);
		cacheItem.setDataSize(0);
		cacheItem.setLasttime(System.currentTimeMillis());
		cacheItem.setData(data);

	}

	/**
	 * 
	 * @param key
	 * @param data
	 * @param dataSize 单位是KB，注意如果或者不到这个值，最好所有填0 ，不要有的0，有的不是
	 */
	public synchronized void setData(String key, T data, Long dataSize) {

		setKey(key);// 排序

		currentNum++;

		totaldataSize += dataSize;

		CacheItem cacheItem = new CacheItem();
		cacheItem.setKey(key);
		cacheItem.setDataSize(dataSize);
		cacheItem.setLasttime(System.currentTimeMillis());
		cacheItem.setData(data);
	}

}
